package org.com.android.polo;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.CursorAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.SimpleAdapter;

import org.com.android.network.*;
import org.com.android.constant.*;

import java.text.SimpleDateFormat;
import java.util.*;

import java.util.ArrayList;

import android.util.Log;

import org.com.android.db.*;
import org.com.android.utility.Utility;
import org.com.android.worker.*;

public class main extends Activity {
	private AutoCompleteTextView barcodeedit;

	private Button scanbutton;

	private ListView barcodelistview;
	private SimpleAdapter listitemadapter;
	private ArrayList<HashMap<String, String>> barcodelist;

	private Map<String, String> conf;

	private Schema schema;

	private NetworkClient networkclient;

	private static final int PROGRESSDLG_SUBMIT_KEY = 0;
	private static final int PROGRESSDLG_SYNC_KEY = 1;

	private Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			int result = msg.getData().getInt("result");
			if (msg.what == Constant.POLO_ACTION_SUBMIT) {
				dismissDialog(PROGRESSDLG_SUBMIT_KEY);
				if (result == Constant.POLO_ACTION_SUBMIT_SUCCESS) {
					updatelistview();
				} else if (result == Constant.POLO_ACTION_SUBMIT_FAILURE) {

				}
			} else if (msg.what == Constant.POLO_ACTION_SYNC) {
				dismissDialog(PROGRESSDLG_SYNC_KEY);
				if (result == Constant.POLO_ACTION_SYNC_SUCCESS) {
					Map<String, String> stamp = new HashMap<String, String>();
					final SimpleDateFormat formatter = new SimpleDateFormat(
							"yyyy-MM-dd HH:mm:ss");
					formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
					stamp.put("stamp", formatter.format(new Date()));
					Utility.saveconf(getSharedPreferences(Constant.CONF, 0),
							stamp);
					conf = Utility.readconf(getSharedPreferences(Constant.CONF,
							0));
				} else if (result == Constant.POLO_ACTION_SYNC_FAILURE) {

				}
			} else {
				Log.e("handleMessage", "you should not come here");
			}
			super.handleMessage(msg);
		}
	};

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		init();
		setlistener();
	}
	

	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case PROGRESSDLG_SUBMIT_KEY: {
			ProgressDialog dialog = new ProgressDialog(this);
			dialog.setTitle("submiting....");
			dialog.setMessage("Please wait while submiting...");
			dialog.setIndeterminate(true);
			dialog.setCancelable(true);
			return dialog;
		}
		case PROGRESSDLG_SYNC_KEY: {
			ProgressDialog dialog = new ProgressDialog(this);
			dialog.setTitle("sync....");
			dialog.setMessage("Please wait while sync...");
			dialog.setIndeterminate(true);
			dialog.setCancelable(true);
			return dialog;
		}
		}
		return null;
	}

	private void setlistener() {
		scanbutton.setOnClickListener(scan);
	}

	private void onremove() {
		String barcode = barcodeedit.getText().toString();
		if (barcode.length() == 0) {
			return;
		}
		removeitem(barcode);
		barcodeedit.setText("");
	}

	private void onsetting() {
	}

	private void onsave() {
		String barcode = barcodeedit.getText().toString();
		if (barcode.length() == 0) {
			return;
		}
		Itable good = getschema().gettable(Good.name);
		ArrayList<Map<String, String>> result = good.query(
				new String[] { "_id" }, "_id =? and status=?", new String[] {
						barcode, String.valueOf(Good.Status.Cached) }, null,
				null, null, null);
		if (result.size() == 0) {
			if (additem(barcode) == false) {
				Log.d("polo::save", "fail to save " + barcode);
			}
		} else {
			Toast.makeText(main.this, barcode + " already exists",
					Toast.LENGTH_LONG).show();
		}
	};

	private Button.OnClickListener scan = new Button.OnClickListener() {
		public void onClick(View v) {
			Intent intent = new Intent("com.google.zxing.client.android.SCAN");
			intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
			startActivityForResult(intent, 0);
		}
	};

	public void onActivityResult(int requestCode, int resultCode, Intent intent) {
		if (requestCode == 0) {
			if (resultCode == RESULT_OK) {
				String contents = intent.getStringExtra("SCAN_RESULT");
				// String format = intent.getStringExtra("SCAN_RESULT_FORMAT");
				// Handle successful scan
				barcodeedit.setText(contents);
			} else if (resultCode == RESULT_CANCELED) {
				// Handle cancel
			}
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		switch (item.getItemId()) {
		case R.id.menu_item_save:
			onsave();
			break;
		case R.id.menu_item_remove:
			onremove();
			break;
		case R.id.menu_item_sync: {
			showDialog(PROGRESSDLG_SYNC_KEY);
			Map<String, String> cond = new HashMap<String, String>();
			cond.put("entity", conf.get("entity"));
			cond.put("lastupdated", conf.get("stamp"));
			Log.d("onMenuItemSelected lastupdate", conf.get("stamp"));
			Worker worker = new Worker(handler, getnetworkclient(), cond,
					schema, Constant.POLO_ACTION_SYNC, "/newgood/sync");
			worker.start();
			break;
		}
		case R.id.menu_item_submit: {
			showDialog(PROGRESSDLG_SUBMIT_KEY);
			Map<String, String> item_to_submit = new HashMap<String, String>();
			item_to_submit.put("barcode", barcodeedit.getText().toString());
			item_to_submit.put("entity", conf.get("entity"));
			Worker worker = new Worker(handler, getnetworkclient(),
					item_to_submit, schema, Constant.POLO_ACTION_SUBMIT,
					"/newgood/sale");
			worker.start();
			break;
		}
		case R.id.menu_item_settings:
			Intent intent = new Intent();
			Bundle bundle = new Bundle();
			intent.setClass(main.this, setting.class);
			startActivity(intent);
			break;
		}
		return super.onMenuItemSelected(featureId, item);
	}

	private Schema getschema() {
		if (schema == null) {
			schema = new Schema(this);
		}
		return schema;
	}

	private NetworkClient getnetworkclient() {
		if (networkclient == null) {
			networkclient = new NetworkClient(conf.get("server"), conf
					.get("username"), conf.get("password"));
		}
		return networkclient;
	}

	private void init() {
		barcodeedit = (AutoCompleteTextView) findViewById(R.id.barcodeedit);
		scanbutton = (Button) findViewById(R.id.scanbutton);

		// init ListView
		barcodelistview = (ListView) findViewById(R.id.barcodelist);
		barcodelist = new ArrayList<HashMap<String, String>>();
		listitemadapter = new SimpleAdapter(this, barcodelist,
				R.layout.listitem, new String[] { "ItemTitle" },
				new int[] { R.id.ItemTitle });
		barcodelistview.setAdapter(listitemadapter);
		barcodelistview.setOnItemClickListener(new ItemClickListener());

		updatelistview();

		// init AutoCompleteTextView
		Cursor cursor = getschema().gettable(Good.name).query(
				new String[] { "_id" }, null, null, null, null, null);
		AutoCompleteAdapter suggestedadapter = new AutoCompleteAdapter(this,
				cursor, 0);
		barcodeedit.setAdapter(suggestedadapter);

		conf = Utility.readconf(getSharedPreferences(Constant.CONF, 0));
	}

	private boolean updatelistview() {
		Map<String, String> cond = new HashMap<String, String>();
		cond.put("status", String.valueOf(Good.Status.Cached));
		ArrayList<Map<String, String>> result = getschema().gettable(Good.name)
				.query(new String[] { "_id" }, "status=?",
						new String[] { String.valueOf(Good.Status.Cached) },
						null, null, null, null);
		barcodelist.clear();
		for (int i = 0; i < result.size(); i++) {
			HashMap<String, String> item = new HashMap<String, String>();
			item.put("ItemTitle", result.get(i).get("_id"));
			Log.d("polo::init", item.get("ItemTitle"));
			barcodelist.add(item);
		}
		listitemadapter.notifyDataSetChanged();
		return true;
	}

	private boolean updateitem(Map<String, String> item) {
		if (item == null) {
			Log.e("main::updateitem", "item = null");
			return false;
		}
		return getschema().gettable(Good.name).update(item);
	}

	private boolean additem(String barcode) {
		HashMap<String, String> item = new HashMap<String, String>();
		item.put("_id", barcode);
		item.put("status", String.valueOf(Good.Status.Cached));
		if (updateitem(item) == false) {
			Log.e("polo::additem", barcode);
			return false;
		} else {
			updatelistview();
		}
		return true;
	}

	private boolean removeitem(String barcode) {
		HashMap<String, String> item = new HashMap<String, String>();
		item.put("_id", barcode);
		item.put("status", String.valueOf(Good.Status.OnSale));
		if (updateitem(item) == false) {
			Log.e("polo::removeitem", barcode);
			return false;
		} else {
			updatelistview();
		}
		return true;
	}

	/*
	 * private Map<String, String> readconf() { SharedPreferences settings =
	 * getSharedPreferences(Constant.CONF, 0); Map<String, String> conf = new
	 * HashMap<String, String>();
	 * 
	 * conf.put("username", settings.getString("username", "ryan"));
	 * conf.put("password", settings.getString("password", "00095313"));
	 * conf.put("server", settings.getString("server",
	 * "http://3d-print.cn:3000")); conf.put("stamp",
	 * settings.getString("stamp", "1982-10-01 00:00:00")); conf.put("entity",
	 * settings.getString("entity", "nanjing"));
	 * 
	 * Log.v("main::readconf", "username:" + conf.get("username"));
	 * Log.v("main::readconf", "password:" + conf.get("password"));
	 * Log.v("main::readconf", "server:" + conf.get("server"));
	 * Log.v("main::readconf", "stamp:" + conf.get("stamp"));
	 * Log.v("main::readconf", "entity:" + conf.get("entity"));
	 * 
	 * return conf; }
	 */

	/*
	 * private void saveconf(Map<String, String> conf) { Editor confeditor =
	 * getSharedPreferences(Constant.CONF, 0) .edit(); for (Map.Entry<String,
	 * String> entry : conf.entrySet()) { confeditor.putString(entry.getKey(),
	 * entry.getValue()); } confeditor.commit(); }
	 */

	class ItemClickListener implements OnItemClickListener {
		public void onItemClick(AdapterView<?> arg0,// The AdapterView where the
				// click happened
				View arg1,// The view within the AdapterView that was clicked
				int arg2,// The position of the view in the adapter
				long arg3// The row id of the item that was clicked
		) {
			// arg2=arg3
			HashMap<String, Object> item = (HashMap<String, Object>) arg0
					.getItemAtPosition(arg2);
			// ItemText
			// item.setLayout(R.layout.listitem) ;
			setTitle((String) item.get("ItemTitle"));
			// arg1.setLayoutParams(params);
			barcodeedit.setText((String) item.get("ItemTitle"));
		}
	}

	class AutoCompleteAdapter extends CursorAdapter {
		private int columnIndex;

		public AutoCompleteAdapter(Context context, Cursor c, int col) {
			super(context, c);
			this.columnIndex = col;
		}

		public View newView(Context context, Cursor cursor, ViewGroup parent) {
			final LayoutInflater inflater = LayoutInflater.from(context);
			final TextView view = (TextView) inflater.inflate(
					android.R.layout.simple_dropdown_item_1line, parent, false);
			view.setText(cursor.getString(columnIndex));
			return view;
		}

		@Override
		public void bindView(View view, Context context, Cursor cursor) {
			((TextView) view).setText(cursor.getString(columnIndex));
		}

		@Override
		public String convertToString(Cursor cursor) {
			return cursor.getString(columnIndex);
		}

		@Override
		public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
			if (constraint != null) {
				String selection = "_id like \'" + constraint.toString()
						+ "%\'";
				selection += " and status = ?";
				return getschema().gettable(Good.name).query(
						new String[] { "_id" }, selection,
						new String[] { String.valueOf(Good.Status.OnSale) },
						null, null, null);
			} else {
				return null;
			}
		}
	}
}
